package com.ics.atable.chat.config;

import com.ics.atable.chat.memory.HistoryAsSystemAdvisor;
import com.ics.atable.chat.service.ChatMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ConcurrentHashMap;

/**
 * ChatClient服务工厂
 *
 * @author haohongbin
 */
@Slf4j
@Configuration
public class ChatClientServiceFactory {

    private static final int MAX_MESSAGES = 10;
    private static final Double TEMPERATURE = 0.7;

    @Value("${spring.ai.openai.base-url}")
    private String baseUrl;

    @Value("${spring.ai.openai.model}")
    private String model;

    @Autowired
    private LlmConfiguration llmConfiguration;

    @Autowired
    private ChatMemory customChatMemory;

    @Autowired
    private ChatMessageService chatMessageService;

    // 缓存ChatClient实例
    private final ConcurrentHashMap<String, ChatClient> chatClientCache = new ConcurrentHashMap<>();

    /**
     * 创建或获取通用ChatClient
     */
    public ChatClient getOrCreateChatClient() {
        String key = "default_" + generateKey(model, baseUrl, TEMPERATURE);
        return chatClientCache.computeIfAbsent(key, k -> {
            ChatModel chatModel = llmConfiguration.getOrCreateChatModel(model, baseUrl, TEMPERATURE);
//            addHistoryToChatMemory(sessionId);
            return ChatClient.builder(chatModel)
                    .defaultAdvisors(
                            MessageChatMemoryAdvisor.builder(customChatMemory).build(),
                            new SimpleLoggerAdvisor()
                    ).build();
        });
    }

    /**
     * 创建或获取意图识别ChatClient
     */
    public ChatClient getOrCreateIntentChatClient() {
        String key = "intent_" + generateKey(model, baseUrl, TEMPERATURE);
        return chatClientCache.computeIfAbsent(key, k -> {
            ChatModel chatModel = llmConfiguration.getOrCreateChatModel(model, baseUrl, TEMPERATURE);
//            addHistoryToChatMemory(sessionId);
            return ChatClient.builder(chatModel)
                    .defaultAdvisors(
                            HistoryAsSystemAdvisor.builder(customChatMemory).build(),
                            new SimpleLoggerAdvisor()
                    ).build();
        });
    }

    /**
     * 创建或获取结构化Token ChatClient
     */
    public ChatClient getOrCreateStructTokenChatClient() {
        String key = "struct_token_" + generateKey(model, baseUrl, TEMPERATURE);
        return chatClientCache.computeIfAbsent(key, k -> {
            ChatModel chatModel = llmConfiguration.getOrCreateChatModel(model, baseUrl, TEMPERATURE);
            return ChatClient.builder(chatModel)
                    .defaultAdvisors(
                            new SimpleLoggerAdvisor()
                    ).build();
        });
    }

    /**
     * 创建或获取同义词 ChatClient
     */
    public ChatClient getOrCreateSynonymsChatClient() {
        String key = "synonyms_" + generateKey(model, baseUrl, TEMPERATURE);
        return chatClientCache.computeIfAbsent(key, k -> {
            ChatModel chatModel = llmConfiguration.getOrCreateChatModel(model, baseUrl, TEMPERATURE);
            return ChatClient.builder(chatModel)
                    .defaultAdvisors(
                            new SimpleLoggerAdvisor()
                    ).build();
        });
    }

    /**
     * 生成缓存key
     */
    private String generateKey(String modelName, String baseUrl, Double temperature) {
        return modelName + "|" + baseUrl + "|" + (temperature != null ? temperature : "null");
    }

    /**
     * 创建ChatMemory实例
     */
    private void addHistoryToChatMemory(String sessionId) {
        // chatMessageService.loadChatHistoryToMemory(sessionId, customChatMemory, 10);
    }
}
